home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / RTF / rtftoken.C < prev    next >
C/C++ Source or Header  |  1994-08-01  |  21KB  |  678 lines

  1. /* rtf.C from
  2.     reader.c - RTF file reader.  Distribution 1.06.
  3.  
  4.     ASCII 10 (\n) and 13 (\r) are ignored and silently discarded.
  5.     (The read hook will still get a look at them.)
  6.  
  7.     "\:" is not a ":", it's a control symbol.  But some versions of
  8.     Word seem to write "\:" for ":".  This reader treats "\:" as a
  9.     plain text ":"
  10.  
  11. */
  12.  
  13. extern "C" {
  14. # include    <ctype.h>
  15. }
  16. # include    <assert.h>
  17. # include       <string.h>
  18.  
  19. # include    "rtftoken.h"
  20.  
  21.  
  22. static int    GetChar ();
  23. static int    HexVal (char);
  24. static void    LookupInit ();
  25. static int    Hash (const char*);
  26.  
  27.  
  28.  
  29. int RTF::inited = 0;
  30.  
  31. RTF::RTF()
  32. {
  33.   if(!inited)
  34.     inited=1, LookupInit();
  35.  
  36.   rtfTextBuf[0] = 0;
  37.   rtfClass = Unknown;
  38. };
  39.  
  40. /* ---------------------------------------------------------------------- */
  41.  
  42. /*
  43.     Token reading routines
  44. */
  45.  
  46.  
  47. /*
  48.     Read the input stream, invoking the writer's callbacks
  49.     where appropriate.
  50. */
  51.  
  52.  
  53. void RTF::SkipGroup ()
  54. {
  55.   int    level = 1;
  56.   
  57.   do{
  58.     if (rtfClass == Group)
  59.       {
  60.     if (rtfMajor == BeginGroup)
  61.       ++level;
  62.     else if (rtfMajor == EndGroup)
  63.       {
  64.         if (--level < 1)
  65.           break;    /* end of initial group */
  66.       }
  67.       }
  68.   }while (GetToken () != Eof);
  69. }
  70.  
  71.  
  72. /*
  73.     Read one token.  Call the read hook if there is one.  The
  74.     token class is the return value.  Returns RTF::Eof when there
  75.     are no more tokens.
  76. */
  77.  
  78. int RTF::GetToken ()
  79. {
  80.   _GetToken ();
  81.  
  82.   /* \n and \r are noise tokens */
  83.   if (rtfClass == Text
  84.       && (rtfMajor == '\n' || rtfMajor == '\r'))
  85.     rtfClass = Unknown;
  86.  
  87.   return (rtfClass);
  88. }
  89.  
  90.  
  91. void RTF::_GetToken ()
  92. {
  93. int    sign;
  94. int    c;
  95.  
  96.     /* initialize token vars */
  97.  
  98.     rtfClass = Unknown;
  99.     rtfParam = 0;
  100.         rtfMinor = 0;
  101.     rtfTextBuf[rtfTextLen = 0] = '\0';
  102.  
  103.     /* get first character, which may be a pushback from previous token */
  104.  
  105.     if ((c = GetChar ()) == EOF)
  106.     {
  107.         rtfClass = EOF;
  108.         return;
  109.     }
  110.  
  111.     if (c == '{')
  112.     {
  113.         rtfClass = Group;
  114.         rtfMajor = BeginGroup;
  115.         return;
  116.     }
  117.     if (c == '}')
  118.     {
  119.         rtfClass = Group;
  120.         rtfMajor = EndGroup;
  121.         return;
  122.     }
  123.     if (c != '\\')
  124.     {
  125.         /*
  126.             Two possibilities here:
  127.             1) ASCII 9, effectively like \tab control symbol
  128.             2) literal text char
  129.         */
  130.         if (c == '\t')            /* ASCII 9 */
  131.         {
  132.             rtfClass = Control;
  133.             rtfMajor = SpecialChar;
  134.             rtfMinor = Tab;
  135.         }
  136.         else
  137.         {
  138.             rtfClass = Text;
  139.             rtfMajor = c;
  140.         }
  141.         return;
  142.     }
  143.     if ((c = GetChar ()) == EOF)
  144.     {
  145.         /* early eof, whoops (class is rtfUnknown) */
  146.         return;
  147.     }
  148.     if (!isalpha (c))
  149.     {
  150.         /*
  151.             Three possibilities here:
  152.             1) hex encoded text char, e.g., \'d5, \'d3
  153.             2) special escaped text char, e.g., \{, \}
  154.             3) control symbol, e.g., \_, \-, \|, \<10>
  155.         */
  156.         if (c == '\'')                /* hex char */
  157.         {
  158.         int    c2;
  159.  
  160.             if ((c = GetChar ()) != EOF && (c2 = GetChar ()) != EOF)
  161.             {
  162.                 /* should do isxdigit check! */
  163.                 rtfClass = Text;
  164.                 rtfMajor = HexVal (c) * 16 + HexVal (c2);
  165.                 rtfMinor = 1;
  166.                 return;
  167.             }
  168.             /* early eof, whoops (class is rtfUnknown) */
  169.             return;
  170.         }
  171.  
  172.         if (strchr (":{}\\", c) != NULL)        /* escaped char */
  173.         {
  174.             rtfClass = Text;
  175.             rtfMajor = c;
  176.             rtfMinor = 2;
  177.             return;
  178.         }
  179.  
  180.         /* control symbol */
  181.         Lookup (rtfTextBuf);    /* sets class, major, minor */
  182.         return;
  183.     }
  184.     /* control word */
  185.     while (isalpha (c))
  186.     {
  187.         if ((c = GetChar ()) == EOF)
  188.             break;
  189.     }
  190.  
  191.     /*
  192.         At this point, the control word is all collected, so the
  193.         major/minor numbers are determined before the parameter
  194.         (if any) is scanned.  There will be one too many characters
  195.         in the buffer, though, so fix up before and restore after
  196.         looking up.
  197.     */
  198.  
  199.     if (c != EOF)
  200.         rtfTextBuf[rtfTextLen-1] = '\0';
  201.     Lookup (rtfTextBuf);    /* sets class, major, minor */
  202.     if (c != EOF)
  203.         rtfTextBuf[rtfTextLen-1] = c;
  204.  
  205.     /*
  206.         Should be looking at first digit of parameter if there
  207.         is one, unless it's negative.  In that case, next char
  208.         is '-', so need to gobble next char, and remember sign.
  209.     */
  210.  
  211.     sign = 1;
  212.     if (c == '-')
  213.     {
  214.         sign = -1;
  215.         c = GetChar ();
  216.     }
  217.     if (c != EOF)
  218.     {
  219.         if(!isdigit(c)) rtfParam = 1; /* so \b defaults to \b1 */
  220.         while (isdigit (c))    /* gobble parameter */
  221.         {
  222.             rtfParam = rtfParam * 10 + c - '0';
  223.             if ((c = GetChar ()) == EOF)
  224.                 break;
  225.         }
  226.         rtfParam *= sign;
  227.     }
  228.     /*
  229.         If control symbol delimiter was a blank, gobble it.
  230.         Otherwise the character is first char of next token, so
  231.         push it back for next call.  In either case, delete the
  232.         delimiter from the token buffer.
  233.     */
  234.     if (c != EOF)
  235.     {
  236.         if (c != ' ')
  237.             pushback(c);
  238.         rtfTextBuf[--rtfTextLen] = '\0';
  239.     }
  240.     return;
  241. }
  242.  
  243.  
  244. /*
  245.     Distributions up through 1.04 assumed high bit could be set in
  246.     RTF file characters.  Beginning with 1.05, that's not true, but
  247.     still check and die if such a character is found.
  248. */
  249.  
  250. int RTF::GetChar ()
  251. {
  252.   int    c = next_char();
  253.  
  254.     rtfTextBuf[rtfTextLen++] = c;
  255.     if (c == NULL)
  256.     {
  257.         rtfTextLen--;
  258.         c = EOF;
  259.     }
  260.     return c;
  261. }
  262.  
  263.  
  264. int HexVal (char c)
  265. {
  266.     if (isupper (c))
  267.         c = tolower (c);
  268.     if (isdigit (c))
  269.         return (c - '0');    /* '0'..'9' */
  270.     return (c - 'a' + 10);        /* 'a'..'f' */
  271. }
  272.  
  273.  
  274. /*
  275.     A minor number of -1 means the token has no minor number
  276.     (all valid minor numbers are >= 0).
  277. */
  278.  
  279. typedef struct 
  280. {
  281.   int     rtfKMajor;      /* major number */
  282.   int     rtfKMinor;      /* minor number */
  283.   char    *rtfKStr;       /* symbol name */
  284.   int     rtfKHash;       /* symbol name hash value */
  285. }RTFKey;
  286.  
  287. static RTFKey    rtfKey[] =
  288. {
  289.   RTF::SpecialChar,    RTF::CurHeadPict,        "chpict",    0,    /* ?? */
  290.     
  291.     RTF::SpecialChar,    RTF::CurHeadDate,        "chdate",    0,
  292.     RTF::SpecialChar,    RTF::CurHeadTime,        "chtime",    0,
  293.     RTF::SpecialChar,    RTF::CurHeadPage,        "chpgn",    0,
  294.     RTF::SpecialChar,    RTF::CurFNote,        "chftn",    0,
  295.     RTF::SpecialChar,    RTF::CurAnnotRef,        "chatn",    0,
  296.     RTF::SpecialChar,    RTF::FNoteSep,        "chftnsep",    0,
  297.     RTF::SpecialChar,    RTF::FNoteCont,        "chftnsepc",    0,
  298.     RTF::SpecialChar,    RTF::Formula,        "|",        0,
  299.     RTF::SpecialChar,    RTF::NoBrkSpace,        "~",        0,
  300.     RTF::SpecialChar,    RTF::NoReqHyphen,        "-",        0,
  301.     RTF::SpecialChar,    RTF::NoBrkHyphen,        "_",        0,
  302.     RTF::SpecialChar,    RTF::Cell,        "cell",        0,
  303.     RTF::SpecialChar,    RTF::Row,            "row",        0,
  304.     RTF::SpecialChar,    RTF::Par,            "par",        0,
  305.     RTF::SpecialChar,    RTF::Par,            "\n",        0,
  306.     RTF::SpecialChar,    RTF::Par,            "\r",        0,
  307.     RTF::SpecialChar,    RTF::Sect,        "sect",        0,
  308.     RTF::SpecialChar,    RTF::Page,        "page",        0,
  309.     RTF::SpecialChar,    RTF::Column,        "column",    0,
  310.     RTF::SpecialChar,    RTF::Line,        "line",        0,
  311.     RTF::SpecialChar,    RTF::Tab,            "tab",        0,
  312.     RTF::SpecialChar,    RTF::OptDest,        "*",        0,
  313.     RTF::SpecialChar,    RTF::IIntVersion,        "vern",        0,
  314.     RTF::SpecialChar,    RTF::ICreateTime,        "creatim",    0,
  315.     RTF::SpecialChar,    RTF::IRevisionTime,    "revtim",    0,
  316.     RTF::SpecialChar,    RTF::IPrintTime,        "printim",    0,
  317.     RTF::SpecialChar,    RTF::IBackupTime,        "buptim",    0,
  318.     RTF::SpecialChar,    RTF::IEditTime,        "edmins",    0,
  319.     RTF::SpecialChar,    RTF::IYear,        "yr",        0,
  320.     RTF::SpecialChar,    RTF::IMonth,        "mo",        0,
  321.     RTF::SpecialChar,    RTF::IDay,        "dy",        0,
  322.     RTF::SpecialChar,    RTF::IHour,        "hr",        0,
  323.     RTF::SpecialChar,    RTF::IMinute,        "min",        0,
  324.     RTF::SpecialChar,    RTF::INPages,        "nofpages",    0,
  325.     RTF::SpecialChar,    RTF::INWords,        "nofwords",    0,
  326.     RTF::SpecialChar,    RTF::INChars,        "nofchars",    0,
  327.     RTF::SpecialChar,    RTF::IIntID,        "id",        0,
  328.     
  329.     RTF::CharAttr,    RTF::Plain,        "plain",    0,
  330.     RTF::CharAttr,    RTF::Bold,        "b",        0,
  331.     RTF::CharAttr,    RTF::Italic,        "i",        0,
  332.     RTF::CharAttr,    RTF::StrikeThru,        "strike",    0,
  333.     RTF::CharAttr,    RTF::Outline,        "outl",        0,
  334.     RTF::CharAttr,    RTF::Shadow,        "shad",        0,
  335.     RTF::CharAttr,    RTF::SmallCaps,        "scaps",    0,
  336.     RTF::CharAttr,    RTF::AllCaps,        "caps",        0,
  337.     RTF::CharAttr,    RTF::Invisible,        "v",        0,
  338.     RTF::CharAttr,    RTF::FontNum,        "f",        0,
  339.     RTF::CharAttr,    RTF::FontSize,        "fs",        0,
  340.     RTF::CharAttr,    RTF::Expand,        "expnd",    0,
  341.     RTF::CharAttr,    RTF::Underline,        "ul",        0,
  342.     RTF::CharAttr,    RTF::WUnderline,        "ulw",        0,
  343.     RTF::CharAttr,    RTF::DUnderline,        "uld",        0,
  344.     RTF::CharAttr,    RTF::DbUnderline,        "uldb",        0,
  345.     RTF::CharAttr,    RTF::NoUnderline,        "ulnone",    0,
  346.     RTF::CharAttr,    RTF::SuperScript,        "up",        0,
  347.     RTF::CharAttr,    RTF::SubScript,        "dn",        0,
  348.     RTF::CharAttr,    RTF::Revised,        "revised",    0,
  349.     RTF::CharAttr,    RTF::ForeColor,        "cf",        0,
  350.     RTF::CharAttr,    RTF::BackColor,        "cb",        0,
  351.     
  352.     RTF::ParAttr,    RTF::ParDef,        "pard",        0,
  353.     RTF::ParAttr,    RTF::StyleNum,        "s",        0,
  354.     RTF::ParAttr,    RTF::QuadLeft,        "ql",        0,
  355.     RTF::ParAttr,    RTF::QuadRight,        "qr",        0,
  356.     RTF::ParAttr,    RTF::QuadJust,        "qj",        0,
  357.     RTF::ParAttr,    RTF::QuadCenter,        "qc",        0,
  358.     RTF::ParAttr,    RTF::FirstIndent,        "fi",        0,
  359.     RTF::ParAttr,    RTF::LeftIndent,        "li",        0,
  360.     RTF::ParAttr,    RTF::RightIndent,        "ri",        0,
  361.     RTF::ParAttr,    RTF::SpaceBefore,        "sb",        0,
  362.     RTF::ParAttr,    RTF::SpaceAfter,        "sa",        0,
  363.     RTF::ParAttr,    RTF::SpaceBetween,    "sl",        0,
  364.     RTF::ParAttr,    RTF::InTable,        "intbl",    0,
  365.     RTF::ParAttr,    RTF::Keep,        "keep",        0,
  366.     RTF::ParAttr,    RTF::KeepNext,        "keepn",    0,
  367.     RTF::ParAttr,    RTF::SideBySide,        "sbys",        0,
  368.     RTF::ParAttr,    RTF::PBBefore,        "pagebb",    0,
  369.     RTF::ParAttr,    RTF::NoLineNum,        "noline",    0,
  370.     RTF::ParAttr,    RTF::TabPos,        "tx",        0,
  371.     RTF::ParAttr,    RTF::TabRight,        "tqr",        0,
  372.     RTF::ParAttr,    RTF::TabCenter,        "tqc",        0,
  373.     RTF::ParAttr,    RTF::TabDecimal,        "tqdec",    0,
  374.     RTF::ParAttr,    RTF::TabBar,        "tb",        0,
  375.     RTF::ParAttr,    RTF::BorderTop,        "brdrt",    0,
  376.     RTF::ParAttr,    RTF::BorderBottom,    "brdrb",    0,
  377.     RTF::ParAttr,    RTF::BorderLeft,        "brdrl",    0,
  378.     RTF::ParAttr,    RTF::BorderRight,        "brdrr",    0,
  379.     RTF::ParAttr,    RTF::BorderBar,        "bar",        0,
  380.     RTF::ParAttr,    RTF::BorderBox,        "box",        0,
  381.     RTF::ParAttr,    RTF::BorderBetween,    "brdrbtw",    0,
  382.     RTF::ParAttr,    RTF::BorderSingle,    "brdrs",    0,
  383.     RTF::ParAttr,    RTF::BorderThick,        "brdrth",    0,
  384.     RTF::ParAttr,    RTF::BorderShadow,    "brdrsh",    0,
  385.     RTF::ParAttr,    RTF::BorderDouble,    "brdrdb",    0,
  386.     RTF::ParAttr,    RTF::BorderDot,        "brdrdot",    0,
  387.     RTF::ParAttr,    RTF::BorderHair,        "brdrhair",    0,
  388.     RTF::ParAttr,    RTF::LeaderDot,        "tldot",    0,
  389.     RTF::ParAttr,    RTF::LeaderHyphen,    "tlhyph",    0,
  390.     RTF::ParAttr,    RTF::LeaderUnder,        "tlul",        0,
  391.     RTF::ParAttr,    RTF::LeaderThick,        "tlth",        0,
  392.     RTF::ParAttr,    RTF::BorderSpace,        "brsp",        0,
  393.     
  394.     RTF::SectAttr,    RTF::SectDef,        "sectd",    0,
  395.     /*rtfSectAttr,    RTF::NoBreak,        "nobreak",    0,
  396.       RTF::SectAttr,    RTF::ColBreak,        "colbreak",    0,
  397.       RTF::SectAttr,    RTF::PageBreak,        "pagebreak",    0,
  398.       RTF::SectAttr,    RTF::EvenBreak,        "evenbreak",    0,
  399.       RTF::SectAttr,    RTF::OddBreak,        "oddbreak",    0,*/
  400.     RTF::SectAttr,    RTF::NoBreak,        "sbknone",    0,
  401.     RTF::SectAttr,    RTF::ColBreak,        "sbkcol",    0,
  402.     RTF::SectAttr,    RTF::PageBreak,        "sbkpage",    0,
  403.     RTF::SectAttr,    RTF::EvenBreak,        "sbkeven",    0,
  404.     RTF::SectAttr,    RTF::OddBreak,        "sbkodd",    0,
  405.     RTF::SectAttr,    RTF::PageCont,        "pgncont",    0,
  406.     RTF::SectAttr,    RTF::PageStarts,        "pgnstarts",    0,
  407.     RTF::SectAttr,    RTF::PageRestart,        "pgnrestart",    0,
  408.     RTF::SectAttr,    RTF::PageDecimal,        "pgndec",    0,
  409.     RTF::SectAttr,    RTF::PageURoman,        "pgnucrm",    0,
  410.     RTF::SectAttr,    RTF::PageLRoman,        "pgnlcrm",    0,
  411.     RTF::SectAttr,    RTF::PageULetter,        "pgnucltr",    0,
  412.     RTF::SectAttr,    RTF::PageLLetter,        "pgnlcltr",    0,
  413.     RTF::SectAttr,    RTF::PageNumLeft,        "pgnx",        0,
  414.     RTF::SectAttr,    RTF::PageNumTop,        "pgny",        0,
  415.     RTF::SectAttr,    RTF::HeaderY,        "headery",    0,
  416.     RTF::SectAttr,    RTF::FooterY,        "footery",    0,
  417.     RTF::SectAttr,    RTF::LineModulus,        "linemod",    0,
  418.     RTF::SectAttr,    RTF::LineDist,        "linex",    0,
  419.     RTF::SectAttr,    RTF::LineStarts,        "linestarts",    0,
  420.     RTF::SectAttr,    RTF::LineRestart,        "linerestart",    0,
  421.     RTF::SectAttr,    RTF::LineRestartPg,    "lineppage",    0,
  422.     RTF::SectAttr,    RTF::LineCont,        "linecont",    0,
  423.     RTF::SectAttr,    RTF::TopVAlign,        "vertalt",    0,
  424.     RTF::SectAttr,    RTF::BottomVAlign,    "vertal",    0,
  425.     RTF::SectAttr,    RTF::CenterVAlign,    "vertalc",    0,
  426.     RTF::SectAttr,    RTF::JustVAlign,        "vertalj",    0,
  427.     RTF::SectAttr,    RTF::Columns,        "cols",        0,
  428.     RTF::SectAttr,    RTF::ColumnSpace,        "colsx",    0,
  429.     RTF::SectAttr,    RTF::ColumnLine,        "linebetcol",    0,
  430.     RTF::SectAttr,    RTF::ENoteHere,        "endnhere",    0,
  431.     RTF::SectAttr,    RTF::TitleSpecial,    "titlepg",    0,
  432.     
  433.     RTF::DocAttr,    RTF::PaperWidth,        "paperw",    0,
  434.     RTF::DocAttr,    RTF::PaperHeight,        "paperh",    0,
  435.     RTF::DocAttr,    RTF::LeftMargin,        "margl",    0,
  436.     RTF::DocAttr,    RTF::RightMargin,        "margr",    0,
  437.     RTF::DocAttr,    RTF::TopMargin,        "margt",    0,
  438.     RTF::DocAttr,    RTF::BottomMargin,    "margb",    0,
  439.     RTF::DocAttr,    RTF::FacingPage,        "facingp",    0,
  440.     RTF::DocAttr,    RTF::GutterWid,        "gutter",    0,
  441.     RTF::DocAttr,    RTF::DefTab,        "deftab",    0,
  442.     RTF::DocAttr,    RTF::WidowCtrl,        "widowctrl",    0,
  443.     RTF::DocAttr,    RTF::HyphHotZone,        "hyphhotz",    0,
  444.     RTF::DocAttr,    RTF::FNoteEndSect,    "endnotes",    0,
  445.     RTF::DocAttr,    RTF::FNoteEndDoc,        "enddoc",    0,
  446.     RTF::DocAttr,    RTF::FNoteBottom,        "ftnbj",    0,
  447.     RTF::DocAttr,    RTF::FNoteText,        "ftntj",    0,
  448.     RTF::DocAttr,    RTF::FNoteStart,        "ftnstart",    0,
  449.     RTF::DocAttr,    RTF::FNoteRestart,    "ftnrestart",    0,
  450.     RTF::DocAttr,    RTF::PageStart,        "pgnstart",    0,
  451.     RTF::DocAttr,    RTF::LineStart,        "linestart",    0,
  452.     RTF::DocAttr,    RTF::Landscape,        "landscape",    0,
  453.     RTF::DocAttr,    RTF::FracWidth,        "fracwidth",    0,
  454.     RTF::DocAttr,    RTF::NextFile,        "nextfile",    0,
  455.     RTF::DocAttr,    RTF::Template,        "template",    0,
  456.     RTF::DocAttr,    RTF::MakeBackup,        "makeback",    0,
  457.     RTF::DocAttr,    RTF::RTFDefault,        "defformat",    0,
  458.     RTF::DocAttr,    RTF::Revisions,        "revisions",    0,
  459.     RTF::DocAttr,    RTF::MirrorMargin,    "margmirror",    0,
  460.     RTF::DocAttr,    RTF::RevDisplay,        "revprop",    0,
  461.     RTF::DocAttr,    RTF::RevBar,        "revbar",    0,
  462.     
  463.     RTF::StyleAttr,    RTF::BasedOn,        "sbasedon",    0,
  464.     RTF::StyleAttr,    RTF::Next,        "snext",    0,
  465.     
  466.     RTF::PictAttr,    RTF::MacQD,        "macpict",    0,
  467.     RTF::PictAttr,    RTF::WinMetafile,        "wmetafile",    0,
  468.     RTF::PictAttr,    RTF::WinBitmap,        "wbitmap",    0,
  469.     RTF::PictAttr,    RTF::PicWid,        "picw",        0,
  470.     RTF::PictAttr,    RTF::PicHt,        "pich",        0,
  471.     RTF::PictAttr,    RTF::PicGoalWid,        "picwgoal",    0,
  472.     RTF::PictAttr,    RTF::PicGoalWid,        "picwGoal",    0,
  473.     RTF::PictAttr,    RTF::PicGoalHt,        "pichgoal",    0,
  474.     RTF::PictAttr,    RTF::PicGoalHt,        "pichGoal",    0,
  475.     RTF::PictAttr,    RTF::PicScaleX,        "picscalex",    0,
  476.     RTF::PictAttr,    RTF::PicScaleY,        "picscaley",    0,
  477.     RTF::PictAttr,    RTF::PicScaled,        "picscaled",    0,
  478.     RTF::PictAttr,    RTF::PicCropTop,        "piccropt",    0,
  479.     RTF::PictAttr,    RTF::PicCropBottom,    "piccropb",    0,
  480.     RTF::PictAttr,    RTF::PicCropLeft,        "piccropl",    0,
  481.     RTF::PictAttr,    RTF::PicCropRight,    "piccropr",    0,
  482.     RTF::PictAttr,    RTF::PixelBits,        "wbmbitspixel",    0,
  483.     RTF::PictAttr,    RTF::BitmapPlanes,    "wbmplanes",    0,
  484.     RTF::PictAttr,    RTF::BitmapWid,        "wbmwidthbytes", 0,
  485.     RTF::PictAttr,    RTF::PicBinary,        "bin",        0,
  486.     
  487.     RTF::Destination,    RTF::Pict,        "pict",        0,
  488.   /* @@ NeXT RTF hacks */
  489.     RTF::Destination,    RTF::Pict,        "NGDocument",    0,
  490.     RTF::Destination,    RTF::Pict,        "NGGraphic",    0,
  491.  
  492.     RTF::Destination,    RTF::Footnote,        "footnote",    0,
  493.     RTF::Destination,    RTF::Header,        "header",    0,
  494.     RTF::Destination,    RTF::HeaderLeft,        "headerl",    0,
  495.     RTF::Destination,    RTF::HeaderRight,        "headerr",    0,
  496.     RTF::Destination,    RTF::HeaderFirst,        "headerf",    0,
  497.     RTF::Destination,    RTF::Footer,        "footer",    0,
  498.     RTF::Destination,    RTF::FooterLeft,        "footerl",    0,
  499.     RTF::Destination,    RTF::FooterRight,        "footerr",    0,
  500.     RTF::Destination,    RTF::FooterFirst,        "footerf",    0,
  501.     RTF::Destination,    RTF::FNSep,        "ftnsep",    0,
  502.     RTF::Destination,    RTF::FNContSep,        "ftnsepc",    0,
  503.     RTF::Destination,    RTF::FNContNotice,    "ftncn",    0,
  504.     RTF::Destination,    RTF::Info,        "info",        0,
  505.     RTF::Destination,    RTF::StyleSheet,        "stylesheet",    0,
  506.     RTF::Destination,    RTF::FontTbl,        "fonttbl",    0,
  507.     RTF::Destination,    RTF::ColorTbl,        "colortbl",    0,
  508.     RTF::Destination,    RTF::Annotation,        "annotation",    0,
  509.     RTF::Destination,    RTF::AnnotID,        "atnid",    0,
  510.     RTF::Destination,    RTF::Field,        "field",    0,
  511.     RTF::Destination,    RTF::FieldInst,        "fldinst",    0,
  512.     RTF::Destination,    RTF::FieldResult,        "fldrslt",    0,
  513.     RTF::Destination,    RTF::Index,        "xe",        0,
  514.     RTF::Destination,    RTF::IndexBold,        "bxe",        0,
  515.     RTF::Destination,    RTF::IndexItalic,        "ixe",        0,
  516.     RTF::Destination,    RTF::IndexText,        "txe",        0,
  517.     RTF::Destination,    RTF::IndexRange,        "rxe",        0,
  518.     RTF::Destination,    RTF::TOC,            "tc",        0,
  519.     RTF::Destination,    RTF::BookmarkStart,    "bkmkstart",    0,
  520.     RTF::Destination,    RTF::BookmarkEnd,        "bkmkend",    0,
  521.     RTF::Destination,    RTF::ITitle,        "title",    0,
  522.     RTF::Destination,    RTF::ISubject,        "subject",    0,
  523.     RTF::Destination,    RTF::IAuthor,        "author",    0,
  524.     RTF::Destination,    RTF::IOperator,        "operator",    0,
  525.     RTF::Destination,    RTF::IKeywords,        "keywords",    0,
  526.     RTF::Destination,    RTF::IComment,        "comment",    0,
  527.     RTF::Destination,    RTF::IVersion,        "version",    0,
  528.     RTF::Destination,    RTF::IDoccomm,        "doccomm",    0,
  529.     
  530.     RTF::TOCAttr,    RTF::TOCType,        "tcf",        0,
  531.     RTF::TOCAttr,    RTF::TOCLevel,        "tcl",        0,
  532.     
  533.     RTF::FontFamily,    RTF::FFNil,        "fnil",        0,
  534.     RTF::FontFamily,    RTF::FFRoman,        "froman",    0,
  535.     RTF::FontFamily,    RTF::FFSwiss,        "fswiss",    0,
  536.     RTF::FontFamily,    RTF::FFModern,        "fmodern",    0,
  537.     RTF::FontFamily,    RTF::FFScript,        "fscript",    0,
  538.     RTF::FontFamily,    RTF::FFDecor,        "fdecor",    0,
  539.     RTF::FontFamily,    RTF::FFTech,        "ftech",    0,
  540.     
  541.     RTF::ColorName,    RTF::Red,            "red",        0,
  542.     RTF::ColorName,    RTF::Green,        "green",    0,
  543.     RTF::ColorName,    RTF::Blue,        "blue",        0,
  544.     
  545.     RTF::CharSet,    RTF::MacCharSet,        "mac",        0,
  546.     RTF::CharSet,    RTF::AnsiCharSet,        "ansi",        0,
  547.     RTF::CharSet,    RTF::PcCharSet,        "pc",        0,
  548.     RTF::CharSet,    RTF::PcaCharSet,        "pca",        0,
  549.     
  550.     RTF::TblAttr,    RTF::CellBordBottom,    "clbrdrb",    0,
  551.     RTF::TblAttr,    RTF::CellBordTop,        "clbrdrt",    0,
  552.     RTF::TblAttr,    RTF::CellBordLeft,    "clbrdrl",    0,
  553.     RTF::TblAttr,    RTF::CellBordRight,    "clbrdrr",    0,
  554.     RTF::TblAttr,    RTF::RowDef,        "trowd",    0,
  555.     RTF::TblAttr,    RTF::RowLeft,        "trql",        0,
  556.     RTF::TblAttr,    RTF::RowRight,        "trqr",        0,
  557.     RTF::TblAttr,    RTF::RowCenter,        "trqc",        0,
  558.     RTF::TblAttr,    RTF::RowGapH,        "trgaph",    0,
  559.     RTF::TblAttr,    RTF::RowHt,        "trrh",        0,
  560.     RTF::TblAttr,    RTF::RowLeftEdge,        "trleft",    0,
  561.     RTF::TblAttr,    RTF::CellPos,        "cellx",    0,
  562.     RTF::TblAttr,    RTF::MergeRngFirst,    "clmgf",    0,
  563.     RTF::TblAttr,    RTF::MergePrevious,    "clmrg",    0,
  564.     
  565.     RTF::FieldAttr,    RTF::FieldDirty,        "flddirty",    0,
  566.     RTF::FieldAttr,    RTF::FieldEdited,        "fldedit",    0,
  567.     RTF::FieldAttr,    RTF::FieldLocked,        "fldlock",    0,
  568.     RTF::FieldAttr,    RTF::FieldPrivate,    "fldpriv",    0,
  569.     
  570.     RTF::PosAttr,    RTF::PosX,        "posx",        0,
  571.     RTF::PosAttr,    RTF::PosXCenter,        "posxc",    0,
  572.     RTF::PosAttr,    RTF::PosXInside,        "posxi",    0,
  573.     RTF::PosAttr,    RTF::PosXLeft,        "posxl",    0,
  574.     RTF::PosAttr,    RTF::PosXOutSide,        "posxo",    0,
  575.     RTF::PosAttr,    RTF::PosXRight,        "posxr",    0,
  576.     RTF::PosAttr,    RTF::PosY,        "posy",        0,
  577.     RTF::PosAttr,    RTF::PosYInline,        "posyil",    0,
  578.     RTF::PosAttr,    RTF::PosYTop,        "posyt",    0,
  579.     RTF::PosAttr,    RTF::PosYCenter,        "posyc",    0,
  580.     RTF::PosAttr,    RTF::PosYBottom,        "posyb",    0,
  581.     RTF::PosAttr,    RTF::AbsWid,        "absw",        0,
  582.     RTF::PosAttr,    RTF::TextDist,        "dxfrtext",    0,
  583.     RTF::PosAttr,    RTF::RPosMargV,        "pvmrg",    0,
  584.     RTF::PosAttr,    RTF::RPosPageV,        "pvpg",        0,
  585.     RTF::PosAttr,    RTF::RPosMargH,        "phmrg",    0,
  586.     RTF::PosAttr,    RTF::RPosPageH,        "phpg",        0,
  587.     RTF::PosAttr,    RTF::RPosColH,        "phcol",    0,
  588.     
  589.     RTF::Version,    -1,            "rtf",        0,
  590.     RTF::DefFont,    -1,            "deff",        0,
  591.     
  592.     0,        -1,            NULL,        0
  593. };
  594.  
  595.  
  596. /*
  597.     Initialize lookup table hash values
  598. */
  599.  
  600. static void LookupInit ()
  601. {
  602. static int    inited = 0;
  603. RTFKey    *rp;
  604.  
  605.     if (inited == 0)
  606.     {
  607.         for (rp = rtfKey; rp->rtfKStr != NULL; rp++)
  608.             rp->rtfKHash = Hash (rp->rtfKStr);
  609.         ++inited;
  610.     }
  611. }
  612.  
  613.  
  614. /*
  615.     Determine major and minor number of control token.  If it's
  616.     not found, the class turns into rtfUnknown.
  617. */
  618.  
  619. void RTF::Lookup (const char* s)
  620. {
  621. RTFKey    *rp;
  622. int    hash;
  623.  
  624.     ++s;            /* skip over the leading \ character */
  625.     hash = Hash (s);
  626.     for (rp = rtfKey; rp->rtfKStr != NULL; rp++)
  627.     {
  628.         if (hash == rp->rtfKHash && strcmp (s, rp->rtfKStr) == 0)
  629.         {
  630.             rtfClass = Control;
  631.             rtfMajor = rp->rtfKMajor;
  632.             rtfMinor = rp->rtfKMinor;
  633.             return;
  634.         }
  635.     }
  636.     rtfClass = Unknown;
  637. }
  638.  
  639.  
  640. /*
  641.     Compute hash value of symbol
  642. */
  643.  
  644. static int Hash (const char* s)
  645. {
  646. char    c;
  647. int    val = 0;
  648.  
  649.     while ((c = *s++) != '\0')
  650.         val += (int) c;
  651.     return (val);
  652. }
  653.  
  654.  
  655. /* ---------------------------------------------------------------------- */
  656.  
  657.  
  658. /*
  659.     Token comparison routines
  660. */
  661.  
  662. int RTF::CheckCM (int c, int major)
  663. {
  664.     return (rtfClass == c && rtfMajor == major);
  665. }
  666.  
  667.  
  668. int RTF::CheckCMM (int c, int major, int minor)
  669. {
  670.     return (rtfClass == c && rtfMajor == major && rtfMinor == minor);
  671. }
  672.  
  673.  
  674. int RTF::CheckMM (int major, int minor)
  675. {
  676.     return (rtfMajor == major && rtfMinor == minor);
  677. }
  678.